package com.xxxx.mail;

import com.rabbitmq.client.Channel;
import com.xxxx.server.pojo.Employee;
import com.xxxx.server.pojo.MailConstants;

import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Date;
@Component
public class MailReceiver {
    private static final Logger LOGGER = LoggerFactory.getLogger(MailReceiver.class);

    //邮件发送
    @Resource
    private JavaMailSender javaMailSender;

    //邮件配置（在appllication.yml中配置的信息）
    @Resource
    private MailProperties mailProperties;

    //模板引擎
    @Resource
    private TemplateEngine templateEngine;

    @Autowired
    private RedisTemplate redisTemplate;

    /*@RabbitListener(queues = "mail.welcome") //监听mail.welcome队列中的消息
    public void sendMail(Employee employee){
        MimeMessage message = javaMailSender.createMimeMessage();//创建消息
        MimeMessageHelper messageHelper = new MimeMessageHelper(message);//封装消息
        try {
            //设置发送人
            messageHelper.setFrom(mailProperties.getUsername());
            //设置收件人
            messageHelper.setTo(employee.getEmail());
            //设置发送主体
            messageHelper.setSubject("入职欢迎邮件");
            //设置发送日期
            messageHelper.setSentDate(new Date());
            //设置邮件内容
            Context context = new Context();
            //如下参数对应mail.html中模板引擎的参数
            context.setVariable("name",employee.getName());
            context.setVariable("posName",employee.getPosition().getName());
            context.setVariable("joblevelName",employee.getJoblevel().getName());
            context.setVariable("departmentName",employee.getDepartment().getName());
            String mail = templateEngine.process("mail", context);//这里mail与mail.html相应
            messageHelper.setText(mail,true); //参数1：邮件参数 参数2：是否是html邮件
            //发送邮件
            javaMailSender.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
            LOGGER.error("邮件发送失败 ========>",e.getMessage());
        }
    }*/
   @RabbitListener(queues = MailConstants.MAIL_QUEUE_NAME)//监听队列中的消息
   public void handler(Message message, Channel channel) {
       //获取员工类
       Employee employee = (Employee) message.getPayload();
       MessageHeaders headers = message.getHeaders();
       //获取消息序号，手动确认时返回
       long tag = (long) headers.get(AmqpHeaders.DELIVERY_TAG);
       //获取消息的msgId
       String msgId = (String) headers.get("spring_returned_message_correlation");
       HashOperations hashOperations = redisTemplate.opsForHash();
       try {
           MimeMessage msg = javaMailSender.createMimeMessage();
           MimeMessageHelper messageHelper = new MimeMessageHelper(msg);
           //判断redis中是否存在msgId，如果有，直接返回
           if (hashOperations.entries("mail_log").containsKey(msgId)) {
               LOGGER.error("消息已经被消费========>{}", msgId);
               /**
                * 手动确认消息
                * tag：消息序号
                * multiple：是否确认多条
                */
               channel.basicAck(tag, false);
               return;
           }
           //设置发送人
           messageHelper.setFrom(mailProperties.getUsername());
           //设置收件人
           messageHelper.setTo(employee.getEmail());
           //设置发送主体
           messageHelper.setSubject("入职欢迎邮件");
           //设置发送日期
           messageHelper.setSentDate(new Date());
           //设置邮件内容
           Context context = new Context();
           //如下参数对应mail.html中模板引擎的参数
           context.setVariable("name", employee.getName());
           context.setVariable("posName", employee.getPosition().getName());
           context.setVariable("joblevelName", employee.getJoblevel().getName());
           context.setVariable("departmentName", employee.getDepartment().getName());
           String mail = templateEngine.process("mail", context);
           messageHelper.setText(mail, true); //参数1：邮件参数 参数2：是否是html邮件
           //发送邮件
           javaMailSender.send(msg);
           LOGGER.info("邮件发送成功 ========>");
           //邮件发送成功后，将msgId标识存入redis
           hashOperations.put("mail_log", msgId, "ok");
           //手动确认消息
           channel.basicAck(tag, false);
       } catch (Exception e) {
           /**
            * 手动确认消息，拒绝接收到的消息，退回到队列，也就是说如果消息的消费出现异常，会将消息退回到队列中
            * @tag 消息序号
            * @multiple 是否处理多条
            * @requeue 是否要退回到队列，如果是false，消息不会重发，
           会把消息打入死信队列。如果是true，会无限次重发导致死循环，不建议加try-catch
            */
           try {
               channel.basicNack(tag, false, true);
           } catch (IOException ioException) {
               ioException.printStackTrace();
           }
           e.printStackTrace();
           LOGGER.error("邮件发送失败 ========>", e.getMessage());
       }
   }
}
